package com.fpf.lab01_basics;

public class Demo5_Volatile {
    /*
    不加 volatile 关键字导致死循环的根本原因是可见性问题：
    子线程无法及时看到主线程对共享变量 running 的修改
    子线程一直使用自己工作内存中过期的 running = true 值
    导致 while (running) 循环无法终止
    这是一个典型的多线程编程中的可见性问题，而 volatile 关键字正是Java中用来解决此类问题的轻量级同步机制。

 */


    //private volatile static boolean running = true;
    private static boolean running = true;
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            while (running) {
                /* busy wait */
            }
            System.out.println("线程感知到running=false，退出循环");
        }).start();
        Thread.sleep(1000);
        running = false;
        System.out.println("主线程修改running=false");
    }
    /*
      1.不加volatile关键字，线程感知不到running=false，无法退出循环
      2.加上volatile关键字，线程感知到running=false，可以退出循环

       不加 volatile 关键字导致死循环的根本原因是可见性问
       初始状态：

      1.主内存中的 running = true
        子线程启动时，将 running = true 复制到自己的工作内存中
        运行时：

      2.子线程在 while (running) 循环中，每次都是读取自己工作内存中的 running 值
        由于循环体内没有任何操作，JVM可能会进行优化，将这个值缓存在寄存器中，不再从工作内存中读取
        主线程修改 running = false，这个修改只更新了主内存中的值，但不会立即刷新到子线程的工作内存中
        结果：

      3.子线程一直认为 running = true
        主线程的修改对子线程不可见
        子线程陷入无限循环，即"死循环"
     */
}

